<!--
 * @Author: wrngygy
 * @Date: 2025-07-01
 * @Description: Vite 代理测试组件
-->

<template>
	<div class="proxy-test">
		<el-card>
			<template #header>
				<h3>Vite 代理配置测试</h3>
			</template>

			<el-row :gutter="20">
				<el-col :span="24">
					<el-alert
						title="代理配置说明"
						type="info"
						description="以下测试将通过不同的代理路径发送请求，验证代理配置是否正常工作"
						show-icon
						:closable="false"
						class="mb-4"
					/>
				</el-col>
			</el-row>

			<el-row :gutter="20" class="mb-4">
				<el-col :span="24">
					<h4>代理路径测试</h4>
					<el-space wrap>
						<el-button
							v-for="proxy in proxyList"
							:key="proxy.path"
							:type="proxy.status === 'success' ? 'success' : proxy.status === 'error' ? 'danger' : 'primary'"
							:loading="proxy.loading"
							@click="testProxy(proxy)"
						>
							{{ proxy.name }}
							<el-icon v-if="proxy.status === 'success'">
								<Check />
							</el-icon>
							<el-icon v-if="proxy.status === 'error'">
								<Close />
							</el-icon>
						</el-button>
					</el-space>
				</el-col>
			</el-row>

			<el-row :gutter="20" class="mb-4">
				<el-col :span="24">
					<h4>环境变量信息</h4>
					<el-descriptions :column="2" border>
						<el-descriptions-item label="应用标题">
							{{ import.meta.env.VITE_APP_TITLE }}
						</el-descriptions-item>
						<el-descriptions-item label="应用环境">
							{{ import.meta.env.VITE_APP_ENV }}
						</el-descriptions-item>
						<el-descriptions-item label="API 基础地址">
							{{ import.meta.env.VITE_API_BASE_URL }}
						</el-descriptions-item>
						<el-descriptions-item label="微信 API 地址">
							{{ import.meta.env.VITE_WX_API_BASE_URL }}
						</el-descriptions-item>
						<el-descriptions-item label="上传服务地址">
							{{ import.meta.env.VITE_UPLOAD_BASE_URL }}
						</el-descriptions-item>
						<el-descriptions-item label="WebSocket 地址">
							{{ import.meta.env.VITE_WS_BASE_URL }}
						</el-descriptions-item>
					</el-descriptions>
				</el-col>
			</el-row>

			<el-row :gutter="20" class="mb-4">
				<el-col :span="24">
					<h4>请求日志</h4>
					<el-card class="log-container">
						<div v-if="logs.length === 0" class="no-logs">
							暂无请求日志
						</div>
						<div v-else class="logs">
							<div
								v-for="(log, index) in logs"
								:key="index"
								class="log-item"
								:class="log.type"
							>
								<span class="log-time">{{ log.time }}</span>
								<span class="log-method">{{ log.method }}</span>
								<span class="log-url">{{ log.url }}</span>
								<span class="log-status" :class="log.status >= 400 ? 'error' : 'success'">
									{{ log.status }}
								</span>
								<span class="log-message">{{ log.message }}</span>
							</div>
						</div>
						<div class="log-actions">
							<el-button size="small" @click="clearLogs">清空日志</el-button>
							<el-button size="small" @click="testAllProxies">测试所有代理</el-button>
						</div>
					</el-card>
				</el-col>
			</el-row>

			<el-row :gutter="20">
				<el-col :span="24">
					<h4>代理配置信息</h4>
					<el-table :data="proxyConfigTable" border>
						<el-table-column prop="path" label="代理路径" width="120" />
						<el-table-column prop="target" label="目标地址" />
						<el-table-column prop="description" label="用途说明" />
						<el-table-column prop="status" label="状态" width="100">
							<template #default="{ row }">
								<el-tag
									:type="row.status === 'success' ? 'success' : row.status === 'error' ? 'danger' : 'info'"
								>
									{{ row.statusText }}
								</el-tag>
							</template>
						</el-table-column>
					</el-table>
				</el-col>
			</el-row>
		</el-card>
	</div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'
import { ElMessage } from 'element-plus'
import { Check, Close } from '@element-plus/icons-vue'

// 代理配置列表
const proxyList = reactive([
	{
		name: 'API 服务',
		path: '/api',
		url: '/api/health',
		method: 'GET',
		target: 'http://localhost:3000',
		description: '主要后端 API 服务',
		loading: false,
		status: '',
	},
	{
		name: '微信 API',
		path: '/wx-api',
		url: '/wx-api/cgi-bin/token',
		method: 'GET',
		target: 'https://api.weixin.qq.com',
		description: '微信小程序 API',
		loading: false,
		status: '',
	},
	{
		name: '上传服务',
		path: '/upload',
		url: '/upload/health',
		method: 'GET',
		target: 'http://localhost:3001',
		description: '文件上传服务',
		loading: false,
		status: '',
	},
	{
		name: '静态资源',
		path: '/static',
		url: '/static/test.json',
		method: 'GET',
		target: 'http://localhost:3003',
		description: '静态资源服务',
		loading: false,
		status: '',
	},
	{
		name: '支付 API',
		path: '/pay-api',
		url: '/pay-api/health',
		method: 'GET',
		target: 'https://api.pay.example.com',
		description: '支付接口服务',
		loading: false,
		status: '',
	},
])

// 请求日志
const logs = ref<any[]>([])

// 代理配置表格数据
const proxyConfigTable = reactive([
	{
		path: '/api',
		target: 'http://localhost:3000',
		description: '主要后端 API 服务',
		status: '',
		statusText: '未测试',
	},
	{
		path: '/wx-api',
		target: 'https://api.weixin.qq.com',
		description: '微信小程序 API（重写路径）',
		status: '',
		statusText: '未测试',
	},
	{
		path: '/upload',
		target: 'http://localhost:3001',
		description: '文件上传服务',
		status: '',
		statusText: '未测试',
	},
	{
		path: '/ws',
		target: 'ws://localhost:3002',
		description: 'WebSocket 连接',
		status: '',
		statusText: '未测试',
	},
	{
		path: '/static',
		target: 'http://localhost:3003',
		description: '静态资源服务',
		status: '',
		statusText: '未测试',
	},
	{
		path: '/pay-api',
		target: 'https://api.pay.example.com',
		description: '支付接口（重写路径 + 认证）',
		status: '',
		statusText: '未测试',
	},
])

// 添加日志
const addLog = (method: string, url: string, status: number, message: string, type = 'info') => {
	logs.value.unshift({
		time: new Date().toLocaleTimeString(),
		method,
		url,
		status,
		message,
		type,
	})
	
	// 限制日志数量
	if (logs.value.length > 50) {
		logs.value = logs.value.slice(0, 50)
	}
}

// 测试单个代理
const testProxy = async (proxy: any) => {
	proxy.loading = true
	proxy.status = ''
	
	try {
		addLog(proxy.method, proxy.url, 0, '开始请求...', 'info')
		
		const response = await fetch(proxy.url, {
			method: proxy.method,
		})
		
		if (response.ok) {
			proxy.status = 'success'
			addLog(proxy.method, proxy.url, response.status, '请求成功', 'success')
			ElMessage.success(`${proxy.name} 代理测试成功`)
			
			// 更新表格状态
			const tableItem = proxyConfigTable.find(item => item.path === proxy.path)
			if (tableItem) {
				tableItem.status = 'success'
				tableItem.statusText = '正常'
			}
		} else {
			proxy.status = 'error'
			addLog(proxy.method, proxy.url, response.status, `请求失败: ${response.statusText}`, 'error')
			ElMessage.error(`${proxy.name} 代理测试失败: ${response.status}`)
			
			// 更新表格状态
			const tableItem = proxyConfigTable.find(item => item.path === proxy.path)
			if (tableItem) {
				tableItem.status = 'error'
				tableItem.statusText = '异常'
			}
		}
	} catch (error: any) {
		proxy.status = 'error'
		addLog(proxy.method, proxy.url, 0, `网络错误: ${error.message}`, 'error')
		ElMessage.error(`${proxy.name} 代理测试失败: ${error.message}`)
		
		// 更新表格状态
		const tableItem = proxyConfigTable.find(item => item.path === proxy.path)
		if (tableItem) {
			tableItem.status = 'error'
			tableItem.statusText = '连接失败'
		}
	} finally {
		proxy.loading = false
	}
}

// 测试所有代理
const testAllProxies = async () => {
	for (const proxy of proxyList) {
		await testProxy(proxy)
		// 添加延迟避免请求过于频繁
		await new Promise(resolve => setTimeout(resolve, 500))
	}
}

// 清空日志
const clearLogs = () => {
	logs.value = []
	ElMessage.success('日志已清空')
}
</script>

<style scoped>
.proxy-test {
	padding: 20px;
}

.mb-4 {
	margin-bottom: 20px;
}

.log-container {
	max-height: 400px;
	overflow-y: auto;
}

.no-logs {
	text-align: center;
	color: #909399;
	padding: 20px;
}

.logs {
	font-family: 'Courier New', monospace;
	font-size: 12px;
}

.log-item {
	display: flex;
	align-items: center;
	padding: 4px 0;
	border-bottom: 1px solid #f0f0f0;
}

.log-item:last-child {
	border-bottom: none;
}

.log-time {
	width: 80px;
	color: #909399;
	margin-right: 10px;
}

.log-method {
	width: 50px;
	font-weight: bold;
	margin-right: 10px;
}

.log-url {
	flex: 1;
	margin-right: 10px;
	color: #409eff;
}

.log-status {
	width: 50px;
	text-align: center;
	margin-right: 10px;
	font-weight: bold;
}

.log-status.success {
	color: #67c23a;
}

.log-status.error {
	color: #f56c6c;
}

.log-message {
	color: #606266;
}

.log-item.success {
	background-color: #f0f9ff;
}

.log-item.error {
	background-color: #fef0f0;
}

.log-actions {
	margin-top: 10px;
	text-align: right;
}

.log-actions .el-button {
	margin-left: 10px;
}
</style>
